/**********************************************************************************
 * Copyright (c) 2012 - 2012,  Collect4PNP, All right reserved
 * Title: com.cipas.pnp.jdbc  ConfigMap.java 
 * @author shen  shenqiao2012@163.com 
 *  2012-7-11 上午10:29:55 
 *********************************************************************************/


package com.adc.jdbc.pool;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.adc.jdbc.constants.DBConstants;
import com.adc.quicktools.ObjectUtil;
import com.adc.quicktools.PropertiesUtil;
import com.adc.quicktools.StringUtil;
import com.adc.quicktools.file.FileControl;
import com.jolbox.bonecp.BoneCPConfig;



public class ConfigMap {
	private static Map<String, BoneCPConfig> boneConfigMap=null;

	/**
	 * 
	 * Description:  获得boneCPConfig的缓存Map
	 * author:  shen  
	 * @return Map<String,BoneCPConfig>
	 */
	public static Map<String, BoneCPConfig> getBoneConfigMap() {
		if (boneConfigMap==null) {
			initConfigMap();
		}
		return boneConfigMap;
	}
	
	/**
	 * 
	 * Description: The initialization of BoneconfigMap
	 * author:  shen 
	 * @return void
	 */
	protected static void initConfigMap(){
		boneConfigMap=new HashMap<String,BoneCPConfig>();
		Properties properties=PropertiesUtil.loadProperties(DBConstants.getConfigPathByName(DBConstants.DB_LIST_CFG));
		if (properties!=null && !properties.isEmpty()) {
			for (int i = 0; i < properties.size(); i++) {
				String poolName=properties.getProperty(DBConstants.getDBConfigName(i+1));
				if (StringUtil.checkStringValue(poolName)) {
					boolean b = addConfigToMap(poolName);
					System.out.println("Initialization Info: Adding[" + poolName + "] " + b);
				}else {
					System.out.println("PoolName ["+poolName+"] is null!");
				}
			}
		}
	}
	
	/**
	 * 
	 * Description: 根据池（配置文件）名称添加配置
	 * author:  shen
	 * @param poolName  
	 * @return boolean
	 */
	@SuppressWarnings("null")
	public static boolean addConfigToMap(String poolName) {
		boolean result=false;
		BoneCPConfig boneCPConfig=null;
		Properties properties=searchForProperties(poolName);
		Properties total=addConfigToDefaultProperties(properties);
//		System.out.println("Config File Content:"+properties.toString());
		System.out.println("Loading Driver:"+total.getProperty(DBConstants.DB_CFG_DRIVER));
		try {
			Class.forName(total.getProperty(DBConstants.DB_CFG_DRIVER));
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		try {
			boneCPConfig=new BoneCPConfig(total);
		} catch (Exception e) {
			e.printStackTrace();
		}
		String key=standardPoolName(poolName);
		if (!boneConfigMap.containsKey(key)) {
			if (boneCPConfig!=null) {
				boneCPConfig.setPoolName(key);
				boneConfigMap.put(key, boneCPConfig);
				result=true;
			}else {
				System.out.println("Can not add [boneCPConfig:name="+boneCPConfig.getPoolName() +"] to Map!");
			}
		}else {
			BoneCPConfig orlCfg=getBoneConfigMap().get(key);
			if (ObjectUtil.objectEquals2(boneCPConfig, orlCfg)) {
				System.out.println(key+" has been added to Map!");
			}else {
				System.out.println("The name["+key+"] of config has been added " +
						"to Map and Current config desn't equal!");
				boneConfigMap.remove(orlCfg);
				boneConfigMap.put(key, boneCPConfig);
				result=true;
			}
		}
		return result;
	}
	
	/**
	 * 
	 * Description:  根据指定的文件名获取配置信息
	 * author:  shen
	 * @param fileName 
	 * @return Properties
	 */
	protected static Properties searchForProperties(String fileName) {
		Properties p=null;
		if (StringUtil.checkStringValue(fileName)) {
			p=new Properties();
			String filePath=DBConstants.getConfigPathByName(fileName);
			p = PropertiesUtil.loadProperties(filePath);
			if (p==null||p.isEmpty()) {
				String aimfilePath = FileControl.fileScanner(StringUtil.getParentByString(filePath), 
						new File(fileName.contains(".properties")?fileName:fileName.concat(".properties")).getName());
				if (StringUtil.checkStringValue(aimfilePath)) {
					p=PropertiesUtil.loadProperties(aimfilePath);
				}
			}
		}
		return p;
	}
	
	/**
	 * 
	 * Description: 将新增加的配置与默认配置拼装到一起；
	 * author:  shen
	 * @param config
	 * @return Properties
	 */
	protected static Properties addConfigToDefaultProperties(Properties config) {
		Properties defaultCfg=DBConstants.loadDefaultConfig();
		Properties properties =null;
		if (config!=null) {
			properties=PropertiesUtil.addProperties(defaultCfg,config , false);
//			for (Iterator i = config.entrySet().iterator(); i.hasNext();) {
//				Entry<String, String> entry = (Entry<String, String>) i.next();
//				for (int j=0;j<properties.size();j++) {
//					if (properties.containsKey(entry.getKey())) {
//						properties.setProperty(entry.getKey(), entry.getValue());
//					}else {
//						properties.put(entry.getKey(), entry.getValue());
//					}
//				}
//			}
		}else {
			properties=PropertiesUtil.copyProperties(defaultCfg, config);
		}
		System.out.println("[After]"+properties);
		return properties;
	}
	
	/**
	 * 
	 * Description: 传入的poolname可以配置文件的全路径，也可以是后缀之前的文件名，
	 * 也可以是“*.properties”；该函数会将会取出文件名除后缀的内容；
	 * author:  shen
	 * @param poolName 
	 * @return String
	 */
	public static String standardPoolName(String poolName) {
		String keyName;
		if (poolName.contains(".properties")&& poolName.contains(File.pathSeparator)) {
			keyName=new File(poolName).getName().split(".")[0];
		}else {
			keyName=poolName;
		}
		System.out.println("Standardization result: " +poolName +" >>keyName: "+keyName);
		return keyName;
	}


}
